<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>PL/Tcl Functions and Arguments</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REV="MADE"
HREF="mailto:pgsql-docs@postgresql.org"><LINK
REL="HOME"
TITLE="PostgreSQL 9.1.2 Documentation"
HREF="index.html"><LINK
REL="UP"
TITLE="PL/Tcl - Tcl Procedural Language"
HREF="pltcl.html"><LINK
REL="PREVIOUS"
TITLE="Overview"
HREF="pltcl-overview.html"><LINK
REL="NEXT"
TITLE="Data Values in PL/Tcl"
HREF="pltcl-data.html"><LINK
REL="STYLESHEET"
TYPE="text/css"
HREF="stylesheet.css"><META
HTTP-EQUIV="Content-Type"
CONTENT="text/html; charset=ISO-8859-1"><META
NAME="creation"
CONTENT="2011-12-01T22:07:59"></HEAD
><BODY
CLASS="SECT1"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="5"
ALIGN="center"
VALIGN="bottom"
><A
HREF="index.html"
>PostgreSQL 9.1.2 Documentation</A
></TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="top"
><A
TITLE="Overview"
HREF="pltcl-overview.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="top"
><A
HREF="pltcl.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="60%"
ALIGN="center"
VALIGN="bottom"
>Chapter 40. PL/Tcl - Tcl Procedural Language</TD
><TD
WIDTH="20%"
ALIGN="right"
VALIGN="top"
><A
TITLE="Data Values in PL/Tcl"
HREF="pltcl-data.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="PLTCL-FUNCTIONS"
>40.2. PL/Tcl Functions and Arguments</A
></H1
><P
>     To create a function in the <SPAN
CLASS="APPLICATION"
>PL/Tcl</SPAN
> language, use
     the standard <A
HREF="sql-createfunction.html"
>CREATE FUNCTION</A
> syntax:

</P><PRE
CLASS="PROGRAMLISTING"
>CREATE FUNCTION <TT
CLASS="REPLACEABLE"
><I
>funcname</I
></TT
> (<TT
CLASS="REPLACEABLE"
><I
>argument-types</I
></TT
>) RETURNS <TT
CLASS="REPLACEABLE"
><I
>return-type</I
></TT
> AS $$
    # PL/Tcl function body
$$ LANGUAGE pltcl;</PRE
><P>

     <SPAN
CLASS="APPLICATION"
>PL/TclU</SPAN
> is the same, except that the language has to be specified as
     <TT
CLASS="LITERAL"
>pltclu</TT
>.
    </P
><P
>     The body of the function is simply a piece of Tcl script.
     When the function is called, the argument values are passed as
     variables <TT
CLASS="LITERAL"
>$1</TT
> ... <TT
CLASS="LITERAL"
>$<TT
CLASS="REPLACEABLE"
><I
>n</I
></TT
></TT
> to the
     Tcl script.  The result is returned
     from the Tcl code in the usual way, with a <TT
CLASS="LITERAL"
>return</TT
>
     statement.
    </P
><P
>     For example, a function
     returning the greater of two integer values could be defined as:

</P><PRE
CLASS="PROGRAMLISTING"
>CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
    if {$1 &gt; $2} {return $1}
    return $2
$$ LANGUAGE pltcl STRICT;</PRE
><P>

     Note the clause <TT
CLASS="LITERAL"
>STRICT</TT
>, which saves us from
     having to think about null input values: if a null value is passed, the
     function will not be called at all, but will just return a null
     result automatically.
    </P
><P
>     In a nonstrict function,
     if the actual value of an argument is null, the corresponding
     <TT
CLASS="LITERAL"
>$<TT
CLASS="REPLACEABLE"
><I
>n</I
></TT
></TT
> variable will be set to an empty string.
     To detect whether a particular argument is null, use the function
     <TT
CLASS="LITERAL"
>argisnull</TT
>.  For example, suppose that we wanted <CODE
CLASS="FUNCTION"
>tcl_max</CODE
>
     with one null and one nonnull argument to return the nonnull
     argument, rather than null:

</P><PRE
CLASS="PROGRAMLISTING"
>CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
    if {[argisnull 1]} {
        if {[argisnull 2]} { return_null }
        return $2
    }
    if {[argisnull 2]} { return $1 }
    if {$1 &gt; $2} {return $1}
    return $2
$$ LANGUAGE pltcl;</PRE
><P>
    </P
><P
>     As shown above,
     to return a null value from a PL/Tcl function, execute
     <TT
CLASS="LITERAL"
>return_null</TT
>.  This can be done whether the
     function is strict or not.
    </P
><P
>     Composite-type arguments are passed to the function as Tcl
     arrays.  The element names of the array are the attribute names
     of the composite type. If an attribute in the passed row has the
     null value, it will not appear in the array. Here is an example:

</P><PRE
CLASS="PROGRAMLISTING"
>CREATE TABLE employee (
    name text,
    salary integer,
    age integer
);

CREATE FUNCTION overpaid(employee) RETURNS boolean AS $$
    if {200000.0 &lt; $1(salary)} {
        return "t"
    }
    if {$1(age) &lt; 30 &amp;&amp; 100000.0 &lt; $1(salary)} {
        return "t"
    }
    return "f"
$$ LANGUAGE pltcl;</PRE
><P>
    </P
><P
>     There is currently no support for returning a composite-type
     result value, nor for returning sets.
    </P
><P
>     <SPAN
CLASS="APPLICATION"
>PL/Tcl</SPAN
> does not currently have full support for
     domain types: it treats a domain the same as the underlying scalar
     type.  This means that constraints associated with the domain will
     not be enforced.  This is not an issue for function arguments, but
     it is a hazard if you declare a <SPAN
CLASS="APPLICATION"
>PL/Tcl</SPAN
> function
     as returning a domain type.
    </P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="pltcl-overview.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="pltcl-data.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Overview</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="pltcl.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Data Values in PL/Tcl</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>